﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using virtuaPol.Model;

namespace virtuaPol.Main
{
    public class GameManager
    {
        private CWorld _world;
        public CWorld World { get { return _world; } set { _world = value; } }

        private Thread _mainThread;
        public Thread MainThread { get { return _mainThread; } }
        private Thread _workerThread;
        public Thread WorkerThread { get { return _workerThread; } }

        private object _locker = new object();

        public UIDispatcher UIDispatcher { get; set; }

        private bool isRunning = false;
        public bool IsRunning {
            get { lock (_locker) { return isRunning; } }
            set { lock (_locker) { isRunning = value; } }
        }

        public event EventHandler<ManagerEventOccurredArgs> EventOccurred;

        public GameManager(CWorld world, UIDispatcher dispatcher)
        {
            World = world;
            UIDispatcher = dispatcher;
            _mainThread = Thread.CurrentThread;
            if(_mainThread.Name != null)
                _mainThread.Name = "UI Thread";
            _workerThread = new Thread(WorkerEntry);
            _workerThread.Name = "Worker Thread";
            _workerThread.SetApartmentState(ApartmentState.STA);
            _workerThread.IsBackground = true;
        }

        ~GameManager()
        {
            //Stop();
        }

        public void Start()
        {
            IsRunning = true;
            _workerThread.Start();
        }

        public void Stop()
        {
            IsRunning = false;
            _workerThread.Join(3000);
            if (_workerThread.IsAlive)
                _workerThread.Abort();
        }

        private void WorkerEntry()
        {
            try
            {
                List<RegisterObjectsStruct> registerObjects
                    = new List<RegisterObjectsStruct>() {
                        new RegisterObjectsStruct("ui", UIDispatcher)
                };

                while (true)
                {
                    if (!IsRunning)
                        break;

                    // Do stuff...

                    foreach (CEvent ev in World.Events)
                    {
                        if (ev.Type == EventType.Silent)
                        {
                            bool success = ev.Execute(World, true, registerObjects);
                            if (success)
                                EventOccurred(this, new ManagerEventOccurredArgs(ev.Name));
                        }
                    }

                    //Thread.Sleep(200);
                }
            }
            catch (ThreadAbortException ex) { }
            catch (Exception ex) { virtuaPol.Util.CLogger.LogError(ex); }
            finally { if (IsRunning) IsRunning = false; }
        }
    }
}
